package com.htthorizon.model.service;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.htthorizon.common.core.constant.Constants;
import com.htthorizon.common.core.utils.DateUtils;
import com.htthorizon.common.core.utils.StringUtils;
import com.htthorizon.common.core.web.domain.AjaxResult;
import com.htthorizon.common.security.utils.SecurityUtils;
import com.htthorizon.model.request.ModelSearchReq;
import com.htthorizon.model.response.RemoteDataInfoDto;
import com.htthorizon.system.api.RemoteUserService;
import com.htthorizon.system.api.domain.SysDept;
import com.htthorizon.system.api.domain.SysUser;
import com.htthorizon.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.htthorizon.model.mapper.ModelSearchMapper;
import com.htthorizon.model.domain.ModelSearch;

import javax.servlet.http.HttpServletResponse;

/**
 * 模型查询条件配置Service业务层处理
 *
 * @author mark
 * @date 2023-11-27
 */
@Service
@Slf4j
public class ModelSearchServiceImpl implements IModelSearchService
{
    @Autowired
    private ModelSearchMapper modelSearchMapper;

    @Autowired
    private IModelCrossAuditService modelCrossAuditService;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private IModelMetaService modelMetaService;

    /**
     * 查询模型查询条件配置
     *
     * @param modelId 模型查询条件配置主键
     * @return 模型查询条件配置
     */
    @Override
    public ModelSearch selectModelSearchByModelId(Long modelId)
    {
        return modelSearchMapper.selectModelSearchByModelId(modelId);
    }

    /**
     * 查询模型查询条件配置列表
     *
     * @param modelSearch 模型查询条件配置
     * @return 模型查询条件配置
     */
    @Override
    public List<ModelSearch> selectModelSearchList(ModelSearch modelSearch)
    {
        return modelSearchMapper.selectModelSearchList(modelSearch);
    }

    /**
     * 新增模型查询条件配置
     *
     * @param modelSearch 模型查询条件配置
     * @return 结果
     */
    @Override
    public int insertModelSearch(ModelSearch modelSearch)
    {
//        ModelSearch modelSearch1=   this.addSearchCondition(modelSearch);

        modelSearch.setCreateTime(DateUtils.getNowDate());
        modelSearch.setCreateBy(SecurityUtils.getUsername());
        modelSearch.setStatus(Constants.DELETE_STATUS_NO);
        return modelSearchMapper.insertModelSearch(modelSearch);
    }

    /**
     * 修改模型查询条件配置
     *
     * @param modelSearch 模型查询条件配置
     * @return 结果
     */
    @Override
    public int updateModelSearch(ModelSearch modelSearch)
    {
//        ModelSearch modelSearch1=   this.addSearchCondition(modelSearch);

        modelSearch.setUpdateTime(DateUtils.getNowDate());
        modelSearch.setUpdateBy(SecurityUtils.getUsername());
        return modelSearchMapper.updateModelSearch(modelSearch);
    }

    private ModelSearch addSearchCondition(ModelSearch modelSearch) {
        String searchJson = modelSearch.getSearchJson();
        JSONArray objects = new JSONArray(searchJson);
        int count=0;
        for (int i=0;i<objects.size();i++){
            JSONObject entries = new JSONObject(objects.get(i));
            if (entries.get("metaFieldName").equals("std_city_org_nm")){
                ++count;
            }
        }
        if (count==0){
            JSONObject entries = new JSONObject();
            entries.putOpt("metaFieldName","std_city_org_nm");
            entries.putOpt("metaFieldRemark","市组织机构");
            entries.putOpt("searchType","6");
            objects.add(entries);
            modelSearch.setSearchJson(com.alibaba.fastjson2.JSONArray.toJSONString(objects));
        }
        return modelSearch;
    }

    public static void main(String[] args) {
//        JSONArray objects = new JSONArray();
//        JSONObject entries=new JSONObject();
//        entries.putOpt("metaFieldName","std_city_org_nm");
//        entries.putOpt("metaFieldRemark","市组织机构");
//        entries.putOpt("searchType","6");
//        objects.add(entries);
//
//        JSONObject entries2=new JSONObject();
//        entries2.putOpt("metaFieldName","std_city_org_nm");
//        entries2.putOpt("metaFieldRemark","市组织机构");
//        entries2.putOpt("searchType","5");
//       objects.add(entries2);
//        System.out.println(com.alibaba.fastjson2.JSONArray.toJSONString(objects));
//        System.out.println(put);
        Set<String> set=new HashSet<>();
        set.add("");
        set.add("1");
        System.out.println(set);
    }

    /**
     * 批量删除模型查询条件配置
     *
     * @param ids 需要删除的模型查询条件配置主键
     * @return 结果
     */
    @Override
    public int deleteModelSearchByIds(Long[] ids)
    {
        return modelSearchMapper.deleteModelSearchByIds(ids);
    }

    /**
     * 删除模型查询条件配置信息
     *
     * @param id 模型查询条件配置主键
     * @return 结果
     */
    @Override
    public int deleteModelSearchById(Long id)
    {
        return modelSearchMapper.deleteModelSearchById(id);
    }

    @Override
    public List<String> getDept() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getSysUser();
        String dept = Optional.ofNullable(sysUser.getDept()).map(SysDept::getDeptName)
                .orElse("");
        log.info("获得部门{}",dept);

        List<String> modelCrossAuditStringList = modelCrossAuditService.getModelCrossAuditStringList();

        SysDept sysDept = Optional.ofNullable(sysUser.getDept()).orElse(new SysDept());
        log.info("获得部门2{}",sysDept);
        if (sysDept.getDeptId()==100){
            List<String> list=  remoteUserService.getDeptList();
            modelCrossAuditStringList.addAll(list);
            modelCrossAuditStringList.add("");
        }else {
            modelCrossAuditStringList.add(dept);
        }
        Set<String> set=new HashSet<>(modelCrossAuditStringList);
        return new ArrayList<>(set);
    }
    private volatile AtomicInteger sign=new AtomicInteger(0);
    @Override
    public void download(HttpServletResponse response, List<List<?>> ajax, ModelSearchReq modelSearch) throws IOException {
        long start = System.currentTimeMillis();
        Map<String,String> metaMap = modelMetaService.getModelFieldsByModelId(modelSearch.getModelId());
        ExcelWriter writer = EasyExcelFactory.write(response.getOutputStream())
                // 核心代码：表头和正文的样式在此
                .build();
        log.info("开始下载个数{}",ajax.size());
        for (int i=0;i<ajax.size();i++){
            Map<String, Object> dataMap = (Map<String, Object>)ajax.get(i).get(0);
            Map<String, Object> columnMap = new LinkedHashMap<>(dataMap.size());
            for(String fieldName:dataMap.keySet()){
                columnMap.put(fieldName,Optional.ofNullable(metaMap.get(fieldName)).orElse(""));
            }

            WriteSheet sheet1 = new WriteSheet();

            sheet1.setSheetName("sheet-"+i);
            sheet1.setSheetNo(i);

            // 创建一个表格，用于 Sheet 中使用
            WriteTable table = new WriteTable();
            table.setTableNo(1);
            // 核心代码：设置表头
            table.setHead(head(columnMap));
            // 写数据
            log.info("{}",i);
            log.info("数据条数{}",ajax.get(i).size());
            log.info("第{}个{}",i,ajax.get(i));
            writer.write(contentData(ajax.get(i)), sheet1, table);

        }
        // 动态添加表头，适用一些表头动态变化的场景
        writer.finish();
        writer.close();
        long end = System.currentTimeMillis();
        log.info("下载耗时{}",(end-start));

    }

    private static List<List<String>> head(Map<String, Object> columnList) {
        List<List<String>> headTitles = ListUtils.newArrayList();
      for(String fieldName:columnList.keySet()){
          headTitles.add(ListUtils.newArrayList( (String) Optional.ofNullable(columnList.get(fieldName)).orElse("")));
      }
        return headTitles;
    }

    private static List<List<Object>> contentData(List<?> list) {
        List<List<Object>> contentList = ListUtils.newArrayList();
        //这里一个List<Object>才代表一行数据，需要映射成每行数据填充，横向填充（把实体数据的字段设置成一个List<Object>）
        //数据根据实际获取进行填充
        for (int i=0;i<list.size();i++){
            List<Object> list1 = new ArrayList<>();
            Map<String, Object> data=   (Map<String, Object>)(list.get(i));
            for(String fieldName:data.keySet()){
                if (StringUtils.isEmpty(fieldName)){
                    list1.add("");
                }
                list1.add(data.get(fieldName));
            }
          contentList.add(list1);
        }
        return contentList;
    }

}
